// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef __H_MK_SCENE_MANAGER__
#define __H_MK_SCENE_MANAGER__

#include "mk_scene_node.h"

namespace MK3DE
{
	class CScene;

	class MK3DE_API CSceneManager
	{
	public:
		CSceneManager();
		~CSceneManager();

		//! Create a empty scene.
		/**
		\param sceneName : the name of the new scene.
		\return : a pointer to the new scene.
		*/
		CScene* CreateScene(const char* sceneName);

		//! Load a scene from scene file.
		/**
		\param scene name : the name of the new scene.
		\param fileName : the file name of the scene file.
		\return : a pointer to the new scene.
		*/
		CScene* LoadSceneFromFile(const char* fileName);

		//! Remove a scene.
		/**
		\param scene : the name of the scene.
		\return : If the method succeeds, return TRUE or return FALSE.
		*/
		BOOL RemoveScene(const char* sceneName);

		//! Get a scene from its name.
		/**
		\param sceneName : the name of the scene.
		\return : the pointer to the scene or NULL.
		*/
		CScene* GetScene(const char* sceneName);

		//! Update all scene.
		void Update(DWORD dt);

	private:
		BOOL __GetSceneByName(const char* name, std::vector<CScene*>::iterator& i);

	private:
		std::vector<CScene*> _vecScene;
	};
	//
	//#if 0
	//    ++-- begin export py interface --++
	//        EXPORT_CONFIG = {
	//            'namespace' : 'MK3DE',
	//            'type' : 'singleton',
	//            'singleton' : 'GetEngine()->GetSceneManager()->',
	//            'method prefix' : 'SM_',
	//            'method list' : 
	//            '''
	//                CSceneNode* CreateSceneNode(CSceneNode* parent, SCENE_NODE_TYPE type);
	//                BOOL DestroySceneNode(CSceneNode* node);
	//                BOOL AddSceneNode(CSceneNode* node);
	//                BOOL RenderAll();
	//
	//            ''',
	//            'py output file' : 'py_scene_manager',
	//            'module name' : 'SceneManager',
	//    }
	//    ++-- end export py interface --++
	//#endif
	//
	//    class CEntitySkyBox;
	//    class CRenderDevice;
	//    class CTexture2D;
	//
	//    enum RENDER_STAGE
	//    {
	//        RS_NORMAL,
	//        RS_REFLECTION,
	//        RS_REFRACTION,
	//    };
	//
	//	class MK3DE_API CSceneManager : public CSceneNode
	//	{
	//	public:
	//		CSceneManager();
	//		~CSceneManager();
	//
	//        SCENE_NODE_TYPE GetType() { return SNT_ROOT; }
	//
	//        //! Create render device.
	//        /**
	//            \param parent : parent scene node. if it's NULL, then the new scene node won't be 
	//                added to scene graph.
	//            \param type : the scene node type.
	//            \return : If the method succeeds, the return value is TRUE. If the method fails, the 
	//                return value is FALSE.
	//        */
	//		CSceneNode* CreateSceneNode(CSceneNode* parent, SCENE_NODE_TYPE type);
	//        BOOL DestroySceneNode(CSceneNode* node);
	//
	//        //! Add a scene node to scene graph
	//        /**
	//            \param node : the pointer of the scene node.
	//            \return : If the method succeeds, the return value is TRUE. If the method fails, the 
	//                return value is FALSE.
	//        */
	//        BOOL AddSceneNode(CSceneNode* node);
	//
	//        //! Load scene from file.
	//        /**
	//            \param fileName : the scene file name.
	//            \return : If the method succeeds, the return value is TRUE. If the method fails, the 
	//                return value is FALSE.
	//        */
	//        BOOL LoadFromFile(const char* fileName);
	//
	//        //! Render the entire scene.
	//        BOOL RenderAll();
	//
	//        BOOL Render();
	//        BOOL PreRender();
	//
	//        RENDER_STAGE GetRenderStage() { return _renderStage; }
	//        CTexture2D* GetReflectionTexture() { return _texReflection; }
	//        CTexture2D* GetRefractionTexture() { return _texRefraction; }
	//
	//    public:
	//        void _AddToRenderQueue(CSceneNode* node);
	//
	//    private:
	//        BOOL __RenderReflectionTexture(CRenderDevice* renderDevice, D3DXPLANE& planeWater);
	//        BOOL __RenderRefractionTexture(CRenderDevice* renderDevice, D3DXPLANE& planeWater);
	//
	//    private:
	//        typedef std::vector<CSceneNode*> RENDER_QUEUE;
	//        RENDER_QUEUE _listRenderQueue[RQT_MAX];
	//        RENDER_QUEUE _listRenderQueueReflection[RQT_MAX];
	//        RENDER_STAGE _renderStage;
	//        CTexture2D* _texReflection;
	//        CTexture2D* _texRefraction;
	//        CEntitySkyBox* _skyBox;
	//	};
};

#endif // __H_MK_SCENE_MANAGER__